#ifndef xpack_lang_cxx_logger_helper
#define xpack_lang_cxx_logger_helper
#pragma push_macro("xuser")
#undef  xuser
#define xuser mixc::lang_cxx::inc
#include"interface/ranger.hpp"
#include"interface/seqptr.hpp"
#include"lang/cxx.hpp"
#include"macro/xdefer.hpp"
#include"memop/copy.hpp"
#include"utils/get_last.hpp"
#include"utils/mix_buffer.hpp"
#include"utils/mix_item.hpp"
#include"utils/unique_array.hpp"
#pragma pop_macro("xuser")

namespace mixc::lang_cxx{
    template<class item_t, class cxx_t = cxx<item_t>>
    inline void logger_helper_corex(
        cxx_t           message, 
        auto    const & items,
        auto          & stream
    ){
        for(auto finished = uxx{}, i = uxx{}; not finished and message->length != zero; i++) {
            // quotes_first 和 label_first 只有一个为 true
            // 指示当前元素是否是纯字符串
            bool quotes_first           = false;
            bool label_first            = false;
            bool in_origin_text         = false;
            uxx  brackets               = 0;

            do {
                auto item               = message[0];

                if (message = message.backward(1); not in_origin_text){
                    switch(stream.output(item); item){
                    case '{':
                    case '(':  brackets++;  break;
                    case '}':
                    case ')':  brackets--;  break;
                    case '\"': 
                        quotes_first    = not label_first; 
                        in_origin_text  = true;
                        break;
                    default:
                        label_first     = label_first or (item != ' ' and not quotes_first);
                        break;
                    }
                }
                else {
                    switch(item){
                    case '\\':
                        stream.output(item_t('\\'));
                        stream.output(item_t(message[0]));
                        message         = message.backward(1);
                        break;
                    case '\"':
                        stream.output(item_t('\"'));
                        in_origin_text  = false;
                        break;
                    default:
                        stream.output(item);
                        break;
                    }
                }

                if (message->length == zero) {
                    finished            = true;
                    break;
                }

                // message 表达式可能包含函数调用，小括号间包含个 ',' 分隔符
                // 例如：message = "a, b, c.call(a, \"hello\", c),"
                // 但需要下列表达式同时满足时才表示结束语义
            }while(message[0] != ',' or brackets != 0 or in_origin_text);

            if (message = message.backward(1); quotes_first){
                continue;
            }

            // 避免 items[i] 越界访问
            if (i >= items->length){
                continue;
            }

            auto    item                   = items[i];
            cxx_t   str;

            if (stream.output(item_t(':')); not item.is_string()) {
                item.format(stream);
            }
            else{
                str                     = item.to_cxx();
                stream.output(item_t('\"'));
                stream.output((item_t *)str, str->length);
                stream.output(item_t('\"'));
            }
        }
    }

    template<class item_t>
    template<class xalloc_t, class ret_t, class>
    inline ret_t cxx<item_t>::logger_helper_core(
        bool is_secret, inc::ranger<mix_item> const & list, xalloc_t const & alloc
    ) const {
        constexpr
        auto is_stream          = the_t::helper::template can_stream<xalloc_t>;
        auto old                = *inner::l_is_secret;  // 先
        *inner::l_is_secret     = is_secret;            // 后，需要单独设置，因为 format() 可能在 alloc 中产生嵌套
        auto result             = the_t{};
        auto allocx             = the_t::helper::stream_helper(alloc, xmodify(result.m_ptr), xmodify(result.m_length));

        the_t::helper::template in_batches<is_stream>(allocx, [&](auto & stream){
            logger_helper_corex<item_t>(xthe, list, stream);
        });

        *inner::l_is_secret     = old;

        if constexpr (inc::is_same<ret_t, the_t>){
            return result;
        }
    }
}

#endif
